﻿namespace WMS6.BLL
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Common;
    using WMS6.Common;
    using WMS6.DALFactory;
    using WMS6.DataEntity;
    using WMS6.DBUtility;
    using WMS6.IDAL;
    using WMS6.QueryEntity;
    using WMS6.DALFactory;

    public class ReceiptDetailLpnBLL
    {
        private static readonly ICommonMethodDA commonMethod = DataAccess.CreateCommonMethod();
        private List<string> dataBaseID;
        private static readonly IGlobalSettingDA globalSettingDA = DataAccess.CreateGlobalSettingDA();
        private int iLpn;
        private static readonly IPackDA packDA = DataAccess.CreatePackDA();
        private PubParasInfo pubParasInfo;
        private static readonly IReceiptDA receiptDA = DataAccess.CreateReceiptDA();
        private static readonly IReceiptDetailDA receiptDetailDA = DataAccess.CreateReceiptDetailDA();
        private static readonly IReceiptDetailLpnDA receiptLpn = DataAccess.CreateReceiptDetailLpnDA();
        private string strLPNGenerateType;

        public ReceiptDetailLpnBLL()
        {
            this.pubParasInfo = null;
            this.iLpn = 0;
            this.strLPNGenerateType = string.Empty;
        }

        public ReceiptDetailLpnBLL(string currentWH)
        {
            this.pubParasInfo = null;
            this.iLpn = 0;
            this.strLPNGenerateType = string.Empty;
            if (!string.IsNullOrEmpty(currentWH))
            {
                this.dataBaseID = commonMethod.GetDataBaseID(currentWH);
                if (this.dataBaseID == null)
                {
                    PublicMethod.GetInstance().ShowAlertMessage("C001");
                }
            }
            else
            {
                PublicMethod.GetInstance().ShowAlertMessage("C002");
            }
        }

        public ReceiptDetailLpnBLL(PubParasInfo tempPubParasInfo)
        {
            this.pubParasInfo = null;
            this.iLpn = 0;
            this.strLPNGenerateType = string.Empty;
            if (!string.IsNullOrEmpty(tempPubParasInfo.CurrentWH))
            {
                this.dataBaseID = commonMethod.GetDataBaseID(tempPubParasInfo.CurrentWH);
                if (this.dataBaseID == null)
                {
                    PublicMethod.GetInstance().ShowAlertMessage("C001", this.pubParasInfo.UserLanguage);
                }
                else
                {
                    this.pubParasInfo = new PubParasInfo();
                    this.pubParasInfo = tempPubParasInfo;
                }
            }
            else
            {
                PublicMethod.GetInstance().ShowAlertMessage("C002", this.pubParasInfo.UserLanguage);
            }
        }

        public string BatchExecutePalletizing(List<string> receiptID)
        {
            string strValue = string.Empty;
            for (int i = 0; receiptID.Count > i; i++)
            {
                try
                {
                    strValue = strValue + this.ExecutePalletizing(receiptID[i]) + ";";
                }
                catch (Exception ex)
                {
                    CommonErrorHandler.ErrorHandler(ex, LogType.Error);
                }
            }
            if (strValue.Length > 0)
            {
                strValue = strValue.Substring(0, strValue.Length - 1);
            }
            return strValue;
        }

        public string BatchRevertPalletizing(List<string> receiptID)
        {
            string strValue = string.Empty;
            for (int i = 0; receiptID.Count > i; i++)
            {
                try
                {
                    strValue = strValue + this.RevertPalletizing(receiptID[i]) + ";";
                }
                catch (Exception ex)
                {
                    CommonErrorHandler.ErrorHandler(ex, LogType.Error);
                }
            }
            if (strValue.Length > 0)
            {
                strValue = strValue.Substring(0, strValue.Length - 1);
            }
            return strValue;
        }

        private ReceiptDetailLpnInfo ConvertToLpnInfo(ReceiptDetailInfo receiptDetailinfo)
        {
            return new ReceiptDetailLpnInfo { 
                WhID = receiptDetailinfo.WhID, ReceiptID = receiptDetailinfo.ReceiptID, ReceiptLineID = receiptDetailinfo.ReceiptLineID, ExternReceiptID = receiptDetailinfo.ExternReceiptID, ExternLineID = receiptDetailinfo.ExternLineID, OwnerID = receiptDetailinfo.OwnerID, PoID = receiptDetailinfo.PoID, PoLineID = receiptDetailinfo.PoLineID, TariffID = receiptDetailinfo.TariffID, SkuID = receiptDetailinfo.SkuID, AltSkuID = receiptDetailinfo.AltSkuID, CaseID = receiptDetailinfo.CaseID, Status = receiptDetailinfo.Status, ReceivedDate = receiptDetailinfo.ReceivedDate, ExpectedQty = receiptDetailinfo.ExpectedQty, AdjustedQty = receiptDetailinfo.AdjustedQty, 
                ReceivedQty = receiptDetailinfo.ReceivedQty, RejectedQty = receiptDetailinfo.RejectedQty, UomID = receiptDetailinfo.UomID, PackID = receiptDetailinfo.PackID, ToLoc = receiptDetailinfo.ToLoc, ToLot = receiptDetailinfo.ToLot, ToLpnID = receiptDetailinfo.ToLpnID, ConditionCode = receiptDetailinfo.ConditionCode, ReceiptLot = receiptDetailinfo.ReceiptLot, CaseCnt = receiptDetailinfo.CaseCnt, InnerPack = receiptDetailinfo.InnerPack, Pallet = receiptDetailinfo.Pallet, Cube = receiptDetailinfo.Cube, GrossWgt = receiptDetailinfo.GrossWgt, NetWgt = receiptDetailinfo.NetWgt, Length = receiptDetailinfo.Length, 
                Width = receiptDetailinfo.Width, Height = receiptDetailinfo.Height, OtherUnit1 = receiptDetailinfo.OtherUnit1, OtherUnit2 = receiptDetailinfo.OtherUnit2, UnitPrice = receiptDetailinfo.UnitPrice, EffectiveDate = receiptDetailinfo.EffectiveDate, Udf1 = receiptDetailinfo.Udf1, Udf2 = receiptDetailinfo.Udf2, Udf3 = receiptDetailinfo.Udf3, Udf4 = receiptDetailinfo.Udf4, Udf5 = receiptDetailinfo.Udf5, Udf6 = receiptDetailinfo.Udf6, Udf7 = receiptDetailinfo.Udf7, Udf8 = receiptDetailinfo.Udf8, Udf9 = receiptDetailinfo.Udf9, Udf10 = receiptDetailinfo.Udf10, 
                ReasonCode = receiptDetailinfo.ReasonCode, PalletID = receiptDetailinfo.PalletID, Type = receiptDetailinfo.Type, ReturnType = receiptDetailinfo.ReturnType, ReturnReason = receiptDetailinfo.ReturnReason, DispositionType = receiptDetailinfo.DispositionType, DispositionCode = receiptDetailinfo.DispositionCode, ReturnCondition = receiptDetailinfo.ReturnCondition, QcRequired = receiptDetailinfo.QcRequired, QcInspectedQty = receiptDetailinfo.QcInspectedQty, QcRejectedQty = receiptDetailinfo.QcRejectedQty, QcRejReason = receiptDetailinfo.QcRejReason, QcStatus = receiptDetailinfo.QcStatus, QcUser = receiptDetailinfo.QcUser, QcAutoAdjust = receiptDetailinfo.QcAutoAdjust, Rma = receiptDetailinfo.Rma, 
                VendorID = receiptDetailinfo.VendorID, VendorName = receiptDetailinfo.VendorName, MatchLottable = receiptDetailinfo.MatchLottable, CrossDockID = receiptDetailinfo.CrossDockID, Remark = receiptDetailinfo.Remark, CreatedBy = receiptDetailinfo.CreatedBy, CreatedDate = receiptDetailinfo.CreatedDate, UpdatedBy = receiptDetailinfo.UpdatedBy, UpdatedDate = receiptDetailinfo.UpdatedDate
             };
        }

        public string ExecutePalletizing(string receiptID)
        {
            string whLoginID = this.dataBaseID[0];
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            try
            {
                ReceiptInfo Receipt = receiptDA.GetReceiptByID(dataBase, tran, receiptID, whLoginID, this.pubParasInfo);
                ReceiptInfo oldReceipt = Receipt;
                if (Receipt != null)
                {
                    if (Receipt.IsPalletized == "Y")
                    {
                        receiptLpn.DeleteReceiptDetailLpn(dataBase, tran, receiptID, whLoginID);
                    }
                    Receipt.ReceiptDetailInfos = receiptDetailDA.GetReceiptDetailListByID(dataBase, tran, receiptID, this.dataBaseID[0], this.pubParasInfo);
                    GlobalSettingInfo globalSettingInfo = globalSettingDA.GetGlobalSettingByID("LPNGenerateType");
                    if (globalSettingInfo != null)
                    {
                        this.strLPNGenerateType = globalSettingInfo.Value;
                    }
                    if ((Receipt.Status.ToUpper() == "NEW") && (Receipt.ReceiptType.ToUpper() != "CASELEVEL"))
                    {
                        int lineID = 1;
                        IPackDA packDA = DataAccess.CreatePackDA();
                        ISkuDA skuDA = DataAccess.CreateSkuDA();
                        foreach (ReceiptDetailInfo info in Receipt.ReceiptDetailInfos)
                        {
                            int remainderQty = Convert.ToInt32(info.ExpectedQty);
                            PackInfo packinfo = packDA.GetPackByID(dataBase, tran, info.PackID, whLoginID);
                            SkuInfo skuInfo = skuDA.GetSkuByID(dataBase, tran, info.OwnerID, info.SkuID, whLoginID);
                            if ((packinfo.IsInLabelUom4 == "Y") && ((Convert.ToInt32(packinfo.Pallet) > 0) && (Convert.ToInt32(packinfo.Pallet) <= Convert.ToInt32(info.ExpectedQty))))
                            {
                                remainderQty = this.PalletizingConversion(dataBase, tran, Convert.ToInt32(info.ExpectedQty), Convert.ToInt32(packinfo.Pallet), packinfo.PackUom4, info, packinfo, false, skuInfo, ref lineID);
                            }
                            if (((packinfo.IsInLabelUom3 == "Y") && (Convert.ToInt32(packinfo.CaseCnt) > 0)) && ((remainderQty > 0) && (remainderQty >= Convert.ToInt32(packinfo.CaseCnt))))
                            {
                                remainderQty = this.PalletizingConversion(dataBase, tran, remainderQty, Convert.ToInt32(packinfo.CaseCnt), packinfo.PackUom3, info, packinfo, false, skuInfo, ref lineID);
                            }
                            if (((packinfo.IsInLabelUom2 == "Y") && (Convert.ToInt32(packinfo.InnerPack) > 0)) && ((remainderQty > 0) && (remainderQty >= Convert.ToInt32(packinfo.InnerPack))))
                            {
                                remainderQty = this.PalletizingConversion(dataBase, tran, remainderQty, Convert.ToInt32(packinfo.InnerPack), packinfo.PackUom2, info, packinfo, false, skuInfo, ref lineID);
                            }
                            if (packinfo.IsInLabelUom1 == "Y")
                            {
                                if ((Convert.ToInt32(packinfo.Qty) > 0) && ((remainderQty > 0) && (remainderQty >= Convert.ToInt32(packinfo.Qty))))
                                {
                                    remainderQty = this.PalletizingConversion(dataBase, tran, remainderQty, Convert.ToInt32(packinfo.Qty), packinfo.PackUom1, info, packinfo, false, skuInfo, ref lineID);
                                }
                            }
                            else if (remainderQty > 0)
                            {
                                remainderQty = this.PalletizingConversion(dataBase, tran, remainderQty, 1, packinfo.PackUom1, info, packinfo, true, skuInfo, ref lineID);
                            }
                        }
                    }
                }
                else
                {
                    return (receiptID + PublicMethod.GetInstance().GetGlobalMsgResource("F4200_018", this.pubParasInfo.UserLanguage));
                }
                Receipt.IsPalletized = "Y";
                receiptDA.UpdateReceipt(dataBase, tran, Receipt, this.dataBaseID[0]);
                AuditDataBLL auditDataBLL = new AuditDataBLL();
                auditDataBLL.InsertAuditData<ReceiptInfo>(dataBase, tran, oldReceipt, Receipt, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT", this.dataBaseID);
                List<ReceiptDetailLpnInfo> oldReceiptDetailLpnInfos = null;
                if ((oldReceiptDetailLpnInfos != null) && (oldReceiptDetailLpnInfos.Count > 0))
                {
                    for (int i = 0; i < oldReceiptDetailLpnInfos.Count; i++)
                    {
                        auditDataBLL.InsertAuditData<ReceiptDetailLpnInfo>(dataBase, tran, oldReceiptDetailLpnInfos[i], null, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT_DETAIL_LPN", this.dataBaseID);
                    }
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return (receiptID + PublicMethod.GetInstance().GetGlobalMsgResource("F4200_019", this.pubParasInfo.UserLanguage));
        }

        public DataSet GetReceiptHistoryByPagerQueryEntity(ReceiptHistoryQueryEntity receiptHistoryQueryEntity)
        {
            List<string> strWhere = new List<string>();
            DataSet dsReceiptHistory = null;
            InboundHelper inboundHelper = new InboundHelper();
            Dictionary<string, PackInfo> packInfoList = new Dictionary<string, PackInfo>();
            dsReceiptHistory = receiptLpn.GetReceiptHistoryByPagerQueryList(strWhere, receiptHistoryQueryEntity, this.dataBaseID[0], this.pubParasInfo);
            if ((dsReceiptHistory != null) && (dsReceiptHistory.Tables.Count > 2))
            {
                for (int i = 0; i < dsReceiptHistory.Tables[2].Rows.Count; i++)
                {
                    PackInfo packInfo = null;
                    if (packInfoList.ContainsKey(dsReceiptHistory.Tables[2].Rows[i]["PACK_ID"].ToString()))
                    {
                        packInfo = packInfoList[dsReceiptHistory.Tables[2].Rows[i]["PACK_ID"].ToString()];
                    }
                    else
                    {
                        packInfo = packDA.GetPackByID(dsReceiptHistory.Tables[2].Rows[i]["PACK_ID"].ToString(), this.dataBaseID[0]);
                        packInfoList.Add(dsReceiptHistory.Tables[2].Rows[i]["PACK_ID"].ToString(), packInfo);
                    }
                    dsReceiptHistory.Tables[2].Rows[i]["RECEIVED_QTY"] = inboundHelper.ExchangeUom(packInfo, dsReceiptHistory.Tables[2].Rows[i]["UOM_ID"].ToString(), Convert.ToDecimal(dsReceiptHistory.Tables[2].Rows[i]["RECEIVED_QTY"]), "R");
                    dsReceiptHistory.Tables[2].Rows[i]["COMPLETED_QTY"] = inboundHelper.ExchangeUom(packInfo, dsReceiptHistory.Tables[2].Rows[i]["UOM_ID"].ToString(), Convert.ToDecimal(dsReceiptHistory.Tables[2].Rows[i]["COMPLETED_QTY"]), "R");
                    dsReceiptHistory.Tables[2].Rows[i]["REMAIN_QTY"] = inboundHelper.ExchangeUom(packInfo, dsReceiptHistory.Tables[2].Rows[i]["UOM_ID"].ToString(), Convert.ToDecimal(dsReceiptHistory.Tables[2].Rows[i]["REMAIN_QTY"]), "R");
                    dsReceiptHistory.Tables[2].Rows[i]["ALLOCATED_QTY"] = inboundHelper.ExchangeUom(packInfo, dsReceiptHistory.Tables[2].Rows[i]["UOM_ID"].ToString(), Convert.ToDecimal(dsReceiptHistory.Tables[2].Rows[i]["ALLOCATED_QTY"]), "R");
                }
            }
            return dsReceiptHistory;
        }

        private int PalletizingConversion(DataBase dataBase, DbTransaction tran, int expectQty, int conversionQty, string unit, ReceiptDetailInfo receiptDetailinfo, PackInfo packInfo, bool isBaseUom, SkuInfo skuInfo, ref int lineID)
        {
            int remainderQty = expectQty / conversionQty;
            try
            {
                if (remainderQty > 0)
                {
                    InboundHelper inboundHelper = new InboundHelper();
                    ReceiptDetailLpnInfo lpnInfo = this.ConvertToLpnInfo(receiptDetailinfo);
                    double cube = lpnInfo.Cube;
                    double grossWgt = lpnInfo.GrossWgt;
                    double netWgt = lpnInfo.NetWgt;
                    if (isBaseUom)
                    {
                        lpnInfo.ReceiptLineID = lineID * 10;
                        lpnInfo.UomID = unit;
                        lpnInfo.ExpectedQty = inboundHelper.ExchangeUom(packInfo, unit, remainderQty, "W");
                        if (expectQty > 0)
                        {
                            lpnInfo.Cube = Convert.ToSingle(lpnInfo.ExpectedQty) * (cube / ((double) expectQty));
                            lpnInfo.GrossWgt = Convert.ToSingle(lpnInfo.ExpectedQty) * (grossWgt / ((double) expectQty));
                            lpnInfo.NetWgt = Convert.ToSingle(lpnInfo.ExpectedQty) * (netWgt / ((double) expectQty));
                        }
                        else
                        {
                            lpnInfo.Cube = 0.0;
                            lpnInfo.GrossWgt = 0.0;
                            lpnInfo.NetWgt = 0.0;
                        }
                        if (string.IsNullOrEmpty(this.strLPNGenerateType) && (this.strLPNGenerateType.ToUpper() != "E-COMMERCE"))
                        {
                            lpnInfo.LpnID = commonMethod.GenNextNumStr(dataBase, tran, "LPN", this.dataBaseID[0]);
                        }
                        else
                        {
                            this.iLpn++;
                            lpnInfo.LpnID = (this.iLpn <= 9) ? ("0" + this.iLpn).ToString() : this.iLpn.ToString();
                        }
                        receiptLpn.InsertReceiptDetailLpn(dataBase, tran, lpnInfo, this.dataBaseID[0]);
                        AuditDataBLL auditDataBLL = new AuditDataBLL();
                        auditDataBLL.InsertAuditData<ReceiptDetailLpnInfo>(dataBase, tran, null, lpnInfo, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT_DETAIL_LPN", this.dataBaseID);
                        lineID++;
                    }
                    else
                    {
                        for (int i = 0; remainderQty > i; i++)
                        {
                            lpnInfo.ReceiptLineID = lineID * 10;
                            lpnInfo.UomID = unit;
                            lpnInfo.ExpectedQty = inboundHelper.ExchangeUom(packInfo, unit, 1M, "W");
                            if (expectQty > 0)
                            {
                                lpnInfo.Cube = Convert.ToSingle(lpnInfo.ExpectedQty) * (cube / ((double) expectQty));
                                lpnInfo.GrossWgt = Convert.ToSingle(lpnInfo.ExpectedQty) * (grossWgt / ((double) expectQty));
                                lpnInfo.NetWgt = Convert.ToSingle(lpnInfo.ExpectedQty) * (netWgt / ((double) expectQty));
                            }
                            else
                            {
                                lpnInfo.Cube = 0.0;
                                lpnInfo.GrossWgt = 0.0;
                                lpnInfo.NetWgt = 0.0;
                            }
                            if (string.IsNullOrEmpty(this.strLPNGenerateType) && (this.strLPNGenerateType.ToUpper() != "E-COMMERCE"))
                            {
                                lpnInfo.LpnID = commonMethod.GenNextNumStr(dataBase, tran, "LPN", this.dataBaseID[0]);
                            }
                            else
                            {
                                this.iLpn++;
                                lpnInfo.LpnID = (this.iLpn <= 9) ? ("0" + this.iLpn).ToString() : this.iLpn.ToString();
                            }
                            receiptLpn.InsertReceiptDetailLpn(dataBase, tran, lpnInfo, this.dataBaseID[0]);
                            new AuditDataBLL().InsertAuditData<ReceiptDetailLpnInfo>(dataBase, tran, null, lpnInfo, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT_DETAIL_LPN", this.dataBaseID);
                            lineID++;
                        }
                    }
                    return (expectQty - (remainderQty * conversionQty));
                }
                remainderQty = expectQty;
            }
            catch (Exception ex)
            {
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            return remainderQty;
        }

        public string RevertPalletizing(string receiptID)
        {
            string whLoginID = this.dataBaseID[0];
            DataBase dataBase = new DataBase();
            DbConnection conn = dataBase.connection;
            conn.Open();
            DbTransaction tran = conn.BeginTransaction();
            try
            {
                ReceiptInfo Receipt = receiptDA.GetReceiptByID(dataBase, tran, receiptID, whLoginID, this.pubParasInfo);
                if (Receipt != null)
                {
                    receiptLpn.DeleteReceiptDetailLpn(dataBase, tran, receiptID, whLoginID);
                    Receipt.IsPalletized = "N";
                    receiptDA.UpdateReceipt(dataBase, tran, Receipt, this.dataBaseID[0]);
                    ReceiptInfo oldReceipt = Receipt;
                    List<ReceiptDetailLpnInfo> oldReceiptDetailLpnInfos = null;
                    AuditDataBLL auditDataBLL = new AuditDataBLL();
                    auditDataBLL.InsertAuditData<ReceiptInfo>(dataBase, tran, oldReceipt, Receipt, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT", this.dataBaseID);
                    if ((oldReceiptDetailLpnInfos != null) && (oldReceiptDetailLpnInfos.Count > 0))
                    {
                        for (int i = 0; i < oldReceiptDetailLpnInfos.Count; i++)
                        {
                            auditDataBLL.InsertAuditData<ReceiptDetailLpnInfo>(dataBase, tran, oldReceiptDetailLpnInfos[i], null, AuditAction.Update, this.pubParasInfo.UserID, "RECEIPT_DETAIL_LPN", this.dataBaseID);
                        }
                    }
                }
                else
                {
                    return (receiptID + PublicMethod.GetInstance().GetGlobalMsgResource("F4200_016", this.pubParasInfo.UserLanguage));
                }
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                CommonErrorHandler.ErrorHandler(ex, LogType.Error);
            }
            finally
            {
                conn.Close();
            }
            return (receiptID + PublicMethod.GetInstance().GetGlobalMsgResource("F4200_017", this.pubParasInfo.UserLanguage));
        }
    }
}

